#include "PersistenciaCanvas.h"
#include "../modelo/Balancin.h"
#include "../modelo/Engranaje.h"
#include "../modelo/Carrito.h"
#include "../modelo/Tijera.h"
#include "../modelo/Polea.h"


// comparacion
bool comparadorElementos(Elemento* elem1, Elemento* elem2) {
	string first = elem1->getTipo();
	string second = elem2->getTipo();
	unsigned int i = 0;

	cout << "Comparo: " << first << " con: " << second;
	while ((i < first.length()) && (i < second.length())) {
		if ((tolower(first[i]) < tolower(second[i]) ||
				first.compare("zpolea")==0) &&
				first.compare("soga")!=0 &&
				second.compare("zpolea")!=0){
				cout << ". Devuelve true" << endl;
				return true;
			}
		else if (tolower(first[i]) > tolower(second[i]) ||
				first.compare("soga")==0 ||
				second.compare("zpolea")==0){
				cout << ". Devuelve false" << endl;
				return false;
			}
		++i;
	}
	if (first.length() < second.length())
		return true;
	else
		return false;
}

PersistenciaCanvas::PersistenciaCanvas(Canvas* canvas) {
	this->canvasaPersistir = canvas;

}

void PersistenciaCanvas::escribirArchivo(string pathYaml) {
	std::ofstream archivo_yaml;
	archivo_yaml.open(pathYaml.c_str());
	YAML::Emitter out;
	out << YAML::BeginMap;
	out << YAML::Key << "fondo" << YAML::Value
			<< this->canvasaPersistir->getRutaFondo();
	out << YAML::Key << "elementos" << YAML::Value << YAML::BeginSeq;

	this->canvasaPersistir->getListaElementos()->sort(comparadorElementos);
	list<Elemento*>::iterator iteradorElementos =
			this->canvasaPersistir->getListaElementos()->begin();

	while (iteradorElementos
			!= this->canvasaPersistir->getListaElementos()->end()) {
		Elemento* elemento = (*iteradorElementos);
		if (!elemento->esBasico()) {
			cout << "elemento no es basicoooo: " << elemento->getTipo() << endl;
			iteradorElementos++;
			continue;
		}
		out << YAML::BeginMap;
		out << YAML::Key << "tipo" << YAML::Value << elemento->getTipo();
		out << YAML::Key << "id" << YAML::Value << elemento->getIdElemento();
		out << YAML::Key << "x" << YAML::Value << elemento->getX();
		out << YAML::Key << "y" << YAML::Value << elemento->getY();
		out << YAML::Key << "angulo" << YAML::Value
				<< elemento->getAnguloRotacion();
		// Guardo el ancho y el alto
		out << YAML::Key << "ancho" << YAML::Value << elemento->getAncho();
		out << YAML::Key << "alto" << YAML::Value << elemento->getAlto();

		// Guardo si es fijo
		if (elemento->isEsFijo()){
			out << YAML::Key << "fijo" << YAML::Value << "true";
		} else {
			out << YAML::Key << "fijo" << YAML::Value << "false";
		}

		if (elemento->getTipo() == "engranaje") {
			Engranaje* engranaje = (Engranaje*) elemento;
			list<Elemento*>::iterator itElementosEngranajes =
					engranaje->obtenerListaEngranajesAsociados()->begin();
			Elemento* engranajeActual;
			stringstream ss;
			list<int> idElementos;
			for (;
					itElementosEngranajes
							!= engranaje->obtenerListaEngranajesAsociados()->end();
					++itElementosEngranajes) {
				engranajeActual = *itElementosEngranajes;
				list<int>::iterator findIter = find(idElementos.begin(),
						idElementos.end(), engranajeActual->getIdElemento());
				if (findIter == idElementos.end()) {
					idElementos.push_back(engranajeActual->getIdElemento());
					ss << " " << engranajeActual->getIdElemento();
				}
			}
			out << YAML::Key << "idUnidos" << YAML::Value << ss.str();
		}
		out << YAML::EndMap;
		iteradorElementos++;
	}

	out << YAML::EndSeq;
	out << YAML::Key << "elementosEspeciales" << YAML::Value << YAML::BeginSeq;
	iteradorElementos = this->canvasaPersistir->getListaElementos()->begin();

	while (iteradorElementos
			!= this->canvasaPersistir->getListaElementos()->end()) {
		Elemento* elemento = (*iteradorElementos);
		if (!elemento->esBasico()) {
			out << YAML::BeginMap;
			out << YAML::Key << "tipo" << YAML::Value << elemento->getTipo();
			out << YAML::Key << "id" << YAML::Value
					<< elemento->getIdElemento();
			out << YAML::Key << "x" << YAML::Value << elemento->getX();
			out << YAML::Key << "y" << YAML::Value << elemento->getY();
			out << YAML::Key << "angulo" << YAML::Value
					<< elemento->getAnguloRotacion();
			// Guardo el ancho y el alto
			out << YAML::Key << "ancho" << YAML::Value << elemento->getAncho();
			out << YAML::Key << "alto" << YAML::Value << elemento->getAlto();

			// Guardo si es fijo
			if (elemento->isEsFijo()){
				out << YAML::Key << "fijo" << YAML::Value << "true";
			} else {
				out << YAML::Key << "fijo" << YAML::Value << "false";
			}


			if (elemento->getTipo() == "soga") {
				pair<Elemento*, Elemento*> extremos =
						elemento->obtenerExtremos();
				out << YAML::Key << "idElem1" << YAML::Value
						<< extremos.first->getIdElemento();
				out << YAML::Key << "idElem2" << YAML::Value
						<< extremos.second->getIdElemento();
			} else if (elemento->getTipo() == "correa") {
				pair<Elemento*, Elemento*> extremos =
						elemento->obtenerExtremos();
				out << YAML::Key << "idElem1" << YAML::Value
						<< extremos.first->getIdElemento();
				out << YAML::Key << "idElem2" << YAML::Value
						<< extremos.second->getIdElemento();
			} else if (elemento->getTipo() == "motor") {
				Elemento* engranaje = elemento->obtenerEngranaje();
				if (engranaje) {
					out << YAML::Key << "idElem1" << YAML::Value
							<< engranaje->getIdElemento();
					out << YAML::Key << "idElem2" << YAML::Value
							<< engranaje->getIdElemento();
				}
				// Sentido de rotacion del motor
				if (elemento->isRotaADerecha()){
					out << YAML::Key << "sentidoRotacion" << YAML::Value << "derecha";
				} else {
					out << YAML::Key << "sentidoRotacion" << YAML::Value << "izquierda";
				}
			} else if (elemento->getTipo() == "flipper") {
				// Sentido de rotacion del flipper
				if (elemento->isRotaADerecha()){
					out << YAML::Key << "sentidoRotacion" << YAML::Value << "derecha";
				} else {
					out << YAML::Key << "sentidoRotacion" << YAML::Value << "izquierda";
				}
			} else if (elemento->getTipo() == "cinta") {
				Elemento* engranaje = elemento->obtenerEngranaje();
				if (engranaje) {
					out << YAML::Key << "idElem1" << YAML::Value
							<< engranaje->getIdElemento();
					out << YAML::Key << "idElem2" << YAML::Value
							<< engranaje->getIdElemento();
				}
			} else if (elemento->getTipo() == "balancin") {
				Balancin* balancin = (Balancin*) elemento;
				pair<Elemento*, Elemento*> extremosBalancin =
						balancin->obtenerExtremos();
				if (extremosBalancin.first) {
					out << YAML::Key << "idElem1" << YAML::Value
							<< extremosBalancin.first->getIdElemento();
				} else {
					out << YAML::Key << "idElem1" << YAML::Value << "0";
				}
				if (extremosBalancin.second) {
					out << YAML::Key << "idElem2" << YAML::Value
							<< extremosBalancin.second->getIdElemento();
				} else {
					out << YAML::Key << "idElem2" << YAML::Value << "0";
				}
			// Persisto el carrito
			} else if (elemento->getTipo() == "carrito") {
				Carrito* carrito = (Carrito*) elemento;
				pair<Elemento*, Elemento*> extremosCarrito =
						carrito->obtenerExtremos();
				if (extremosCarrito.first) {
					out << YAML::Key << "idElem1" << YAML::Value
							<< extremosCarrito.first->getIdElemento();
				} else {
					out << YAML::Key << "idElem1" << YAML::Value << "0";
				}
				if (extremosCarrito.second) {
					out << YAML::Key << "idElem2" << YAML::Value
							<< extremosCarrito.second->getIdElemento();
				} else {
					out << YAML::Key << "idElem2" << YAML::Value << "0";
				}
			// Persisto la tijera
			} else if (elemento->getTipo() == "atijera") {
				Tijera* tijera = (Tijera*) elemento;
				pair<Elemento*, Elemento*> extremosTijera =
						tijera->obtenerExtremos();
				if (extremosTijera.first) {
					out << YAML::Key << "idElem1" << YAML::Value
							<< extremosTijera.first->getIdElemento();
				} else {
					out << YAML::Key << "idElem1" << YAML::Value << "0";
				}
				if (extremosTijera.second) {
					out << YAML::Key << "idElem2" << YAML::Value
							<< extremosTijera.second->getIdElemento();
				} else {
					out << YAML::Key << "idElem2" << YAML::Value << "0";
				}
			// Persisto la polea
			} else if (elemento->getTipo() == "zpolea") {
				Polea* polea = (Polea*) elemento;
				pair<Elemento*, Elemento*> extremosPolea =
						polea->obtenerExtremos();
				if (extremosPolea.first) {
					out << YAML::Key << "idElem1" << YAML::Value
							<< extremosPolea.first->getIdElemento();
				} else {
					out << YAML::Key << "idElem1" << YAML::Value << "0";
				}
				if (extremosPolea.second) {
					out << YAML::Key << "idElem2" << YAML::Value
							<< extremosPolea.second->getIdElemento();
				} else {
					out << YAML::Key << "idElem2" << YAML::Value << "0";
				}
			}
			out << YAML::EndMap;
		}
		iteradorElementos++;
	}
	out << YAML::EndSeq;

	out << YAML::EndMap;

	archivo_yaml << out.c_str();
	archivo_yaml.close();
}

PersistenciaCanvas::~PersistenciaCanvas() {
// TODO Auto-generated destructor stub
}

void PersistenciaCanvas::setCanvas(Canvas* canvas) {
	this->canvasaPersistir = canvas;
}

